/**
 * @file ajoutArbre.c
 * @brief Fichier source du module ajoutArbre.
 *
 * @author Rachid Delory, Mamadou Keita, Florian Bernard
 */

/* *********************************************************************

                       Librairies de AjoutArbre

********************************************************************* */

#include "ajoutArbre.h"

/* *********************************************************************

                        Fonctions                                      

********************************************************************* */

void selectionChanged(GtkTreeSelection *selection, gpointer data)
{
  GtkTreeIter iter;
  gint type;
  void * dataVoid;
  
  GtkTreeModel *model;
  AjoutPane *panel = data;
  if(gtk_tree_selection_get_selected(selection, &model, &iter))
    {
      /* Une nouvelle sélection */
      Arbre *arb;
      Oeuvre *oeuvre;
      gtk_widget_set_visible(getContainer_GAPan(panel), TRUE);
      
      gtk_tree_model_get (model, &iter, TYPE_COLUMN, &type, 
			  ARBRE_COLUMN, &dataVoid, -1);
      
      switch(type)
	{
	case REGROUPEMENT_OEU:
	  arb = dataVoid; 
	  setInformationRegroupement_GAPan(panel, arb);
	  break;
	default:
	  oeuvre = dataVoid;
	  if(oeuvre != NULL)
	    setInformationOeuvre_GAPan(panel, oeuvre);
	  else
	    gtk_widget_set_visible(getContainer_GAPan(panel), FALSE);
	  break;
	}
    }
  else
    {
      /* We need to hide the hide panel */
      gtk_widget_set_visible(getContainer_GAPan(panel), FALSE);
    }
}

gboolean titreChanged(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
  AjoutArbre *aArbre = user_data;
  GtkTreeView *tree = GTK_TREE_VIEW(aArbre->gArbre);
  GtkTreeIter iterPrt;
  GtkTreeModel *model;
  GtkTreeSelection *select;

  select = gtk_tree_view_get_selection(tree);
  if(gtk_tree_selection_get_selected(select, &model, &iterPrt))
    {
      gtk_tree_store_set(GTK_TREE_STORE(model), &iterPrt, TITRE_COLUMN, gtk_entry_get_text(GTK_ENTRY(widget)), -1);
    }
  return FALSE;
  (void)event;
}

void typeChanged_AArb(GtkWidget *widget, gpointer user_data)
{
  AjoutArbre *aArbre = user_data;
  GtkTreeView *tree = GTK_TREE_VIEW(aArbre->gArbre);
  GtkTreeIter iterPrt;
  GtkTreeModel *model;
  GtkTreeSelection *select;

  select = gtk_tree_view_get_selection(tree);
  if(gtk_tree_selection_get_selected(select, &model, &iterPrt))
    {
      gtk_tree_store_set(GTK_TREE_STORE(model), &iterPrt, TYPE_COLUMN, gtk_combo_box_get_active(GTK_COMBO_BOX(widget)), -1);
    }
}

void testLigneVide(GtkTreeModel *model, GtkTreeIter *iterPrt)
{
  int type;
  if(gtk_tree_model_iter_n_children(model, iterPrt) == 1)
    {
      GtkTreeIter iterRm;
	      
      if(gtk_tree_model_iter_children(model, &iterRm, iterPrt))
	{
	  gtk_tree_model_get(model, &iterRm, TYPE_COLUMN, &type, -1);
	  if(type == VIDE_OEU)
	    gtk_tree_store_remove(GTK_TREE_STORE(model), &iterRm);
	}
    }
}

void insertionArbreTreeStore(Arbre *arbre, GtkTreeStore *store, GtkTreeIter *iterPrt)
{
  if(arbre)
    {
      Regroupement *reg = getInformation(arbre);
      int i, taille;
      Ensemble *ens;
      GtkTreeIter iter;
      GtkTreeIter iterEnf;

      gtk_tree_store_append(store, &iter, iterPrt);
      gtk_tree_store_set (store, &iter, 
			  TITRE_COLUMN, (
					 getTitre_Reg(reg) == NULL ?
					 "" :
					 getTitre_Reg(reg)
					 ),
			  TYPE_COLUMN, REGROUPEMENT_OEU,
			  ARBRE_COLUMN, arbre,
			  -1);
      if(estVide_Arb(arbre))
	{
	  gtk_tree_store_append(store, &iterEnf, &iter);
	  gtk_tree_store_set(store, &iterEnf,
			     TITRE_COLUMN, "vide",
			     TYPE_COLUMN, VIDE_OEU,
			     -1);
	}
      else
	{
	  ens = recupSousArbre_Arb(arbre);
	  taille = getTaille_Ens(ens);
	  prems_Ens(ens);
	  for(i = 0; i < taille; i++)
	    {	      
	      insertionArbreTreeStore(getData_Ens(ens), store, &iter);
	      suivant_Ens(ens);
	    }
	  ens = recupFeuille_Arb(arbre);
	  taille = getTaille_Ens(ens);
	  prems_Ens(ens);
	  for(i = 0; i < taille; i++)
	    {
	      Oeuvre *oeuvre = getData_Ens(ens);
	      gtk_tree_store_append(store, &iterEnf, &iter);
	      gtk_tree_store_set (store, &iterEnf, 
				  TITRE_COLUMN, getTitre_Oeu(oeuvre) == NULL ? "" : getTitre_Oeu(oeuvre),
				  TYPE_COLUMN, AUCUN_OEU,
				  ARBRE_COLUMN, oeuvre,
				  -1);
	      suivant_Ens(ens);
	    }
	}
    }
}

void listeFichierCB(GtkButton *btn, gpointer data)
{
  GtkWidget *dialog;
  GtkWidget *combo;
  GtkWidget *content_area;
  GtkWidget *vbox;
  
  /** Todo ajout du type de recherche (film, musique livre)*/
  dialog = gtk_file_chooser_dialog_new("Sélection du dossier", 
				       NULL, 
				       GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, 
				       GTK_STOCK_CANCEL, 
				       GTK_RESPONSE_CANCEL, 
				       GTK_STOCK_OPEN, 
				       GTK_RESPONSE_ACCEPT, 
				       NULL);
  combo = gtk_combo_box_text_new();
  gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo), NULL, "Film");
  gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo), NULL, "Musique");
  gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo), NULL, "Livre");
  gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo), NULL, "Tous");
  gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
  vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 1);
  gtk_box_pack_start(GTK_BOX(vbox), combo, FALSE, FALSE, 1);
  
  content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));

  gtk_container_add(GTK_CONTAINER(content_area), vbox);
  gtk_widget_show_all(dialog);
  if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
    {
      char *filename;
      Arbre *arbre;
      AjoutArbre *aArbre = data;
      GtkTreeView *tree = GTK_TREE_VIEW(aArbre->gArbre);
      GtkTreeModel *model;
      GtkTreeSelection *select;
      GtkTreeIter iter;
      gchar *gtype;
      int type;
      gtype = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(combo));
      
      if(strcmp(gtype, "Film") == 0)
	type = FILM_LFI;
      else if(strcmp(gtype, "Musique") == 0)
	type = MUSIQUE_LFI;
      else if(strcmp(gtype, "Livre") == 0)
	type = LIVRE_LFI;
      else
	type = TOUS_LFI;
      g_free(gtype);
      filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
      select = gtk_tree_view_get_selection(tree);
      arbre = listeDossierArbre_Lfi(filename, 
				    type
				    );
      if(!gtk_tree_selection_get_selected(select, &model, &iter))
	{
	  ajoutNoeud_Arb(aArbre->gtkArbre->arbre, arbre);
	  insertionArbreTreeStore(arbre, 
				  aArbre->gtkArbre->store, NULL);
	}
      else
	{
	  int type;
	  Arbre *arbrePrt;
	  gtk_tree_model_get(model, &iter,
			     TYPE_COLUMN, &type,
			     ARBRE_COLUMN, &arbrePrt,
			     -1);
	  if(type == REGROUPEMENT_OEU)
	    {
	      ajoutNoeud_Arb(arbrePrt, arbre);
	      testLigneVide(model, &iter);
	      insertionArbreTreeStore(arbre, 
				      GTK_TREE_STORE(model), &iter);
	    }
	  else
	    {
	      GtkTreeIter iterPrt;
	      if(gtk_tree_model_iter_parent(model, &iterPrt, &iter))
		{
		  gtk_tree_model_get(model, &iterPrt,
				     ARBRE_COLUMN, &arbrePrt,
				     -1);
		  ajoutNoeud_Arb(arbrePrt, arbre);
		  testLigneVide(model, &iterPrt);
		  insertionArbreTreeStore(arbre,
					  GTK_TREE_STORE(model), 
					  &iterPrt);
		}
	      else
		{
		  ajoutNoeud_Arb(aArbre->gtkArbre->arbre, arbre);
		  insertionArbreTreeStore(arbre,
					  GTK_TREE_STORE(model),
					  NULL);
		}
	    }
	}
      g_free(filename);
    }
  gtk_widget_destroy(dialog);
  (void)btn;
}

void ajoutRegroupementCB(GtkButton *btn, gpointer data)
{
  AjoutArbre *aArbre = data;
  GtkTreeView *tree = GTK_TREE_VIEW(aArbre->gArbre);
  GtkTreeIter iterPrt;
  GtkTreeModel *model;
  GtkTreeSelection *select;
  GtkTreeIter iter;
  GtkTreeStore *store;
  Ensemble *ens;
  Regroupement *reg = creer_Reg();
  Arbre *arbre;
  setTitre_Reg(reg, "Dossier");
  arbre = creer_Arb(reg);
  detruire_Reg(&reg);
  select = gtk_tree_view_get_selection(tree);
  if(gtk_tree_selection_get_selected(select, &model, &iterPrt))
    {
      Arbre *arbPrt;
      int type;

      gtk_tree_model_get(model, &iterPrt, TYPE_COLUMN, &type, -1);
      store = GTK_TREE_STORE(model);
      if(type == REGROUPEMENT_OEU)
	{
	  gtk_tree_model_get(model, &iterPrt, ARBRE_COLUMN, &arbPrt, -1);
	  ajoutNoeud_Arb(arbPrt, arbre);
	  ens = recupSousArbre_Arb(arbPrt);
	  testLigneVide(model, &iterPrt);
	  gtk_tree_store_append(store, &iter, &iterPrt);
	}
      else 
	{
	  GtkTreeIter iterParent;
	  if(gtk_tree_model_iter_parent(model, &iterParent, &iterPrt))
	    {
	      gtk_tree_model_get(model, &iterParent, ARBRE_COLUMN, &arbPrt, -1);
	      ajoutNoeud_Arb(arbPrt, arbre);
	      ens = recupSousArbre_Arb(arbPrt);

	      testLigneVide(model, &iterParent);
	      gtk_tree_store_append(store, &iter, &iterParent);
	    }
	  else
	    {
	      ajoutNoeud_Arb(aArbre->gtkArbre->arbre, arbre);
	      ens = recupSousArbre_Arb(aArbre->gtkArbre->arbre);
	      testLigneVide(GTK_TREE_MODEL(store), &iter);
	      gtk_tree_store_append(store, &iter, NULL);

	    }
	}

    }
  else
    {
      ajoutNoeud_Arb(aArbre->gtkArbre->arbre, arbre);
      ens = recupSousArbre_Arb(aArbre->gtkArbre->arbre);
      store = GTK_TREE_STORE(model);
      gtk_tree_store_append(store, &iter, NULL);
    }
  setMaj_Ens(ens, 1);
  gtk_tree_store_set (store, &iter, 
		      TITRE_COLUMN, "Dossier",
		      TYPE_COLUMN, REGROUPEMENT_OEU,
		      ARBRE_COLUMN, arbre,
		      -1);
  (void)btn;
}

void ajoutOeuvreCB(GtkButton *btn, gpointer data)
{
  AjoutArbre *aArbre = data;
  GtkTreeView *tree = GTK_TREE_VIEW(aArbre->gArbre);
  GtkTreeIter iterPrt;
  GtkTreeModel *model;
  GtkTreeSelection *select;
  GtkTreeIter iter;
  GtkTreeStore *store;
  Ensemble *ens;
  Oeuvre *oeuvre = creer_Oeu();
  setTitre_Oeu(oeuvre, "Oeuvre");
  select = gtk_tree_view_get_selection(tree);
  if(gtk_tree_selection_get_selected(select, &model, &iterPrt))
    {
      Arbre *arbPrt;
      int type;

      store = GTK_TREE_STORE(model);
      gtk_tree_model_get(model, &iterPrt, TYPE_COLUMN, &type, -1);
      store = GTK_TREE_STORE(model);
      if(type == REGROUPEMENT_OEU)
	{
	  gtk_tree_model_get(model, &iterPrt, ARBRE_COLUMN, &arbPrt, -1);
	  ajoutFeuille_Arb(arbPrt, oeuvre);
	  ens = recupFeuille_Arb(arbPrt);
	  detruire_Oeu(&oeuvre);
	  oeuvre = getData_Ens(recupFeuille_Arb(arbPrt));
	  testLigneVide(model, &iterPrt);
	  gtk_tree_store_append(store, &iter, &iterPrt);
	}
      else 
	{
	  GtkTreeIter iterParent;
	  if(gtk_tree_model_iter_parent(model, &iterParent, &iterPrt))
	    {
	      gtk_tree_model_get(model, &iterParent, ARBRE_COLUMN, &arbPrt, -1);
	      ajoutFeuille_Arb(arbPrt, oeuvre);
	      ens = recupFeuille_Arb(arbPrt);
	      detruire_Oeu(&oeuvre);
	      oeuvre = getData_Ens(recupFeuille_Arb(arbPrt));
	      testLigneVide(model, &iterParent);
	      gtk_tree_store_append(store, &iter, &iterParent);
	    }
	  else
	    {
	      ajoutFeuille_Arb(aArbre->gtkArbre->arbre, oeuvre);
	      ens = recupFeuille_Arb(aArbre->gtkArbre->arbre);
	      detruire_Oeu(&oeuvre);
	      oeuvre = getData_Ens(recupFeuille_Arb(aArbre->gtkArbre->arbre));
	      gtk_tree_store_append(store, &iter, NULL);
	    }
	}
    }
  else
    {
      ajoutFeuille_Arb(aArbre->gtkArbre->arbre, oeuvre);
      ens = recupFeuille_Arb(aArbre->gtkArbre->arbre);
      detruire_Oeu(&oeuvre);
      oeuvre = getData_Ens(recupFeuille_Arb(aArbre->gtkArbre->arbre));
      store = GTK_TREE_STORE(model);
      gtk_tree_store_append(store, &iter, NULL);
    }
  setMaj_Ens(ens, 1);
  gtk_tree_store_set (store, &iter, 
		      TITRE_COLUMN, "Oeuvre",
		      TYPE_COLUMN, AUCUN_OEU,
		      ARBRE_COLUMN, oeuvre,
		      -1);
  (void)btn;
}

void suppression(GtkTreeStore *store, GtkTreeIter *iter)
{
  int type;

  gtk_tree_model_get(GTK_TREE_MODEL(store), iter, TYPE_COLUMN, &type, -1);
  if(type == REGROUPEMENT_OEU)
    {
      Arbre *arb;
      gtk_tree_model_get(GTK_TREE_MODEL(store), iter, ARBRE_COLUMN, &arb, -1);
      setSup_Arb(arb, 1);
      setSup_Reg(getInformation(arb), 1);
      gtk_tree_store_remove(store, iter);
    }
  else
    {
      Oeuvre *oeuvre;
      gtk_tree_model_get(GTK_TREE_MODEL(store), iter, ARBRE_COLUMN, &oeuvre, -1);
      setSup_Oeu(oeuvre, 1);
      switch(getType_Oeu(oeuvre))
	{
	case FILM_OEU:
	  setSup_Fil((Film *) getMedia_Oeu(oeuvre), 1);
	  break;
	case MUSIQUE_OEU:
	  setSup_Mus((Musique *) getMedia_Oeu(oeuvre), 1);
	  break;
	case LIVRE_OEU:
	  setSup_Liv((Livre *) getMedia_Oeu(oeuvre), 1);
	  break;
	default:
	  break;
	}

      gtk_tree_store_remove(store, iter);
    }
}

void suppressionCB(GtkButton *btn, gpointer data)
{
  AjoutArbre *aArbre = data;
  GtkTreeView *tree = GTK_TREE_VIEW(aArbre->gArbre);
  GtkTreeSelection *select;
  GtkTreeModel *model;
  GtkTreeIter iter;
  select = gtk_tree_view_get_selection(tree);
  if(gtk_tree_selection_get_selected(select, &model, &iter))
    {
      GtkTreeIter iterPrt;
      gboolean valid;
      /* Suppression de tout les enfants si c'est un regroupement */
      /* Suppression de la ligne si c'est une oeuvre */
      /* En fonction de la colonne TYPE_COLUMN_GAARB */
      valid = gtk_tree_model_iter_parent(model, &iterPrt, &iter);

      suppression(GTK_TREE_STORE(model), &iter);
      if(valid)
	{
	  if(gtk_tree_model_iter_n_children(model, &iterPrt) == 0)
	    {
	      gtk_tree_store_append(aArbre->gtkArbre->store, &iter, &iterPrt);
	      gtk_tree_store_set (aArbre->gtkArbre->store, &iter,
				  TITRE_COLUMN, "vide",
				  TYPE_COLUMN, VIDE_OEU,
				  -1);

	    }
	}
    }
  (void)btn;
}

void expandedCB(GtkTreeView *tree_view, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data)
{
  AjoutArbre *aArbre = user_data;
  Arbre *arb;
  int id;
  GtkTreeIter iterEnfant;
  GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
  
  gtk_tree_model_get(model, iter,
		     ID_COLUMN, &id,
		     ARBRE_COLUMN, &arb,
		     -1);
  if(estVide_Arb(arb) == 1)
    {
      if(id != 0)
	{
	  recuperation_DReg(arb, id, 1);
	  recuperation_DOeu(arb, id);
	  recuperation_Arbre_GArb(aArbre->gtkArbre->store, arb, iter, 1);
	}
      if(gtk_tree_model_iter_n_children(model, iter) != 1)
	{
	  if(gtk_tree_model_iter_children(model, &iterEnfant, iter))
	    gtk_tree_store_remove(aArbre->gtkArbre->store, &iterEnfant);
	}
      else
	{
	  if(gtk_tree_model_iter_children(model, &iterEnfant, iter))
	    gtk_tree_store_set(aArbre->gtkArbre->store, &iterEnfant, TITRE_COLUMN, "vide",
			       TYPE_COLUMN, VIDE_OEU,
			       -1);
	}
    }
  (void)path;
}

AjoutArbre * creer_GAArb(AjoutPane *pane, GtkArbre *gtkArbre)
{
  GtkTreeViewColumn *column;
  GtkCellRenderer *renderer;
  /*  GtkTreeStore *store;*/
  GtkWidget *scroll;
  GtkTreeSelection *select;
  GtkWidget *btnRegroupement;
  GtkWidget *btnOeuvre;
  GtkWidget *btnSuppression;
  GtkWidget *btnListeFichier;
  GtkWidget *hbox;
  AjoutArbre *aArbre = (AjoutArbre *)malloc(1*sizeof(AjoutArbre));
  aArbre->gtkArbre = gtkArbre;
  aArbre->vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 1);
  
  hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 1);

  btnRegroupement = gtk_button_new_from_stock(GTK_STOCK_DIRECTORY);
  gtk_box_pack_start(GTK_BOX(hbox), btnRegroupement, FALSE, FALSE, 1);
  btnOeuvre = gtk_button_new_from_stock(GTK_STOCK_NEW);
  gtk_box_pack_start(GTK_BOX(hbox), btnOeuvre, FALSE, FALSE, 1);
  btnSuppression = gtk_button_new_from_stock(GTK_STOCK_DELETE);
  gtk_box_pack_start(GTK_BOX(hbox), btnSuppression, FALSE, FALSE, 1);
  btnListeFichier = gtk_button_new_from_stock(GTK_STOCK_OPEN);
  gtk_box_pack_start(GTK_BOX(hbox), btnListeFichier, FALSE, FALSE, 1);
  gtk_box_pack_start(GTK_BOX(aArbre->vbox), hbox, FALSE, FALSE, 1);

  aArbre->gArbre = gtk_tree_view_new_with_model(GTK_TREE_MODEL(gtkArbre->store));
  renderer = gtk_cell_renderer_text_new();
  column = gtk_tree_view_column_new_with_attributes("Titre",
						    renderer,
						    "text", 
						    TITRE_COLUMN,
						    NULL);
  gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN(column), TRUE);
  gtk_tree_view_append_column(GTK_TREE_VIEW(aArbre->gArbre), column);

  /*  
  renderer = gtk_cell_renderer_text_new();
  column = gtk_tree_view_column_new_with_attributes("Type",
						    renderer,
						    "text", 
						    TYPE_COLUMN,
						    NULL);
  gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN(column), TRUE);
  gtk_tree_view_append_column(GTK_TREE_VIEW(aArbre->gArbre), column);

  renderer = gtk_cell_renderer_text_new();
  column = gtk_tree_view_column_new_with_attributes("Data",
						    renderer,
						    "text", 
						    ARBRE_COLUMN,
						    NULL);
  gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN(column), TRUE);
  gtk_tree_view_append_column(GTK_TREE_VIEW(aArbre->gArbre), column);
  */

  scroll = gtk_scrolled_window_new(NULL, NULL);
  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), aArbre->gArbre);
  gtk_box_pack_start(GTK_BOX(aArbre->vbox), scroll, TRUE, TRUE, 1);

  select = gtk_tree_view_get_selection (GTK_TREE_VIEW(aArbre->gArbre));
  gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);

  g_signal_connect(G_OBJECT(select), "changed", G_CALLBACK(selectionChanged), pane);
  g_signal_connect(aArbre->gArbre, "row-expanded", G_CALLBACK(expandedCB), aArbre);
  g_signal_connect(btnRegroupement, "clicked", G_CALLBACK(ajoutRegroupementCB), aArbre);
  g_signal_connect(btnOeuvre, "clicked", G_CALLBACK(ajoutOeuvreCB), aArbre);
  g_signal_connect(btnSuppression, "clicked", G_CALLBACK(suppressionCB), aArbre);
  g_signal_connect(btnListeFichier, "clicked", G_CALLBACK(listeFichierCB), aArbre);
  return aArbre;
}

GtkWidget *getContainer_GAArb(AjoutArbre *aArbre)
{
  return aArbre->vbox;
}

void detruire_GAArb(AjoutArbre **aArbre)
{
  free((*aArbre));
}

Arbre *getArbre_GAArb(AjoutArbre *aArbre)
{
  return aArbre->gtkArbre->arbre;
}
